package com.xingshi.springbootinit.mq;

import com.rabbitmq.client.Channel;
import com.xingshi.springbootinit.annotation.ScoreReturn;
import com.xingshi.springbootinit.common.ErrorCode;
import com.xingshi.springbootinit.common.ResultUtils;
import com.xingshi.springbootinit.constant.BiMqConstant;
import com.xingshi.springbootinit.constant.CommonConstant;
import com.xingshi.springbootinit.exception.BusinessException;
import com.xingshi.springbootinit.manager.SparkAiManager;
import com.xingshi.springbootinit.model.entity.Chart;
import com.xingshi.springbootinit.service.ChartService;
import com.xingshi.springbootinit.websocket.WebSocketServer;
import lombok.SneakyThrows;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class BiMessageConsumer {

    @Resource
    private ChartService chartService;

    @Resource
    private SparkAiManager sparkAiManager;

    @Resource
    private WebSocketServer webSocketServer;

    /**
     * 接收消息
     * @param message
     * @param channel
     * @param deliveryTag
     */
    @SneakyThrows //@SneakyThrows 注解时，Lombok 会生成一个包装受检异常的代码，而不需要你显式地编写 try-catch 块或者在方法上使用 throws 声明。
    @RabbitListener(queues = {BiMqConstant.BI_QUEUE_NAME},ackMode = "MANUAL")
    public void receiveMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag){

        if(StringUtils.isBlank(message)){
            channel.basicNack(deliveryTag,false,false);
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"消息为空");
        }

        long chartId = Long.parseLong(message);
        Chart chart = chartService.getById(chartId);

        if (chart == null){
            channel.basicNack(deliveryTag,false,false);
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"消息中指向的图表为空");
        }

        //修改任务为执行中
        Chart updateToRunning = new Chart();
        updateToRunning.setId(chart.getId());
        updateToRunning.setStatus("running");
        updateToRunning.setExecMessage(null);
        boolean succeed = chartService.updateById(updateToRunning);
        if(!succeed){
            channel.basicNack(deliveryTag,false,false);
            chartService.handleChartUpdateError(chart.getId(), "更新图表执行中状态失败");
            return;
        }

        //调用讯飞星火大模型
        String userInput = chartService.buildUserInput(chart);
        String result = sparkAiManager.dochat(userInput);

        //结果校验
        String[] splits = result.split("【【【【【");
        if (splits.length < 3) {
            channel.basicNack(deliveryTag,false,false);
            chartService.handleChartUpdateError(chart.getId(), CommonConstant.AI_GENERATION_FAILED);
            return;
        }
        String genChart = splits[1].trim();
        String genResult = splits[2].trim();
        boolean isValidJson = chartService.isValidJson(genChart);
        if (!isValidJson) {
            channel.basicNack(deliveryTag,false,false);
            chartService.handleChartUpdateError(chart.getId(),CommonConstant.AI_GENERATION_FAILED);
            return;
        }

        //得到AI回复后，再更新一次，修改任务状态为成功
        Chart updateToSucceed = new Chart();
        updateToSucceed.setId(chart.getId());
        updateToSucceed.setGenChart(genChart);
        updateToSucceed.setGenResult(genResult);
        updateToSucceed.setStatus("succeed");
        boolean updateResult = chartService.updateById(updateToSucceed);
        if(!updateResult){
            channel.basicNack(deliveryTag,false,false);
            chartService.handleChartUpdateError(chart.getId(), "更新图表成功状态失败");
            return;
        }
        //通知客户端图表生成成功
        String userId = chart.getUserId().toString();
        String notice = "图表生成好了，赶紧去看看吧！";
        webSocketServer.sendToAllClient(notice);
        //消息确认
        channel.basicAck(deliveryTag,false);
    }
}
